const path = require('path');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const Jimp = require('jimp');
const PDFDocument = require('pdfkit');

/**
 * 调整图片大小以限制内存使用
 * @param {Jimp} image - Jimp图像对象
 * @param {number} maxDimension - 最大尺寸（宽或高）
 * @returns {Jimp} - 调整后的图像
 */
const resizeImageIfNeeded = (image, maxDimension = 1500) => {
  const width = image.getWidth();
  const height = image.getHeight();
  
  // 如果图片尺寸超过最大限制，则进行缩放
  if (width > maxDimension || height > maxDimension) {
    if (width > height) {
      return image.resize(maxDimension, Jimp.AUTO);
    } else {
      return image.resize(Jimp.AUTO, maxDimension);
    }
  }
  
  return image;
};

/**
 * 增强文档图像
 * @param {string} imagePath - 原始图像路径
 * @returns {Promise<string>} - 处理后的图像路径
 */
exports.enhanceDocument = async (imagePath) => {
  try {
    console.log(`开始处理图片: ${imagePath}`);
    const outputPath = path.join(
      path.dirname(imagePath),
      `enhanced-${path.basename(imagePath)}`
    );
    
    // 使用Jimp进行图像处理
    let image = await Jimp.read(imagePath);
    console.log(`图片加载成功，原始尺寸: ${image.getWidth()}x${image.getHeight()}`);
    
    // 调整图片大小以限制内存使用
    image = resizeImageIfNeeded(image);
    console.log(`图片尺寸调整后: ${image.getWidth()}x${image.getHeight()}`);
    
    // 图像处理：灰度化、对比度增强、锐化
    image
      .greyscale()           // 灰度化
      .contrast(0.2)         // 增加对比度
      .normalize()           // 标准化
      .brightness(0.05)      // 轻微提高亮度
      .quality(85);          // 降低质量以减少文件大小
    
    console.log(`图片处理完成，准备保存到: ${outputPath}`);
    
    // 保存处理后的图像
    await image.writeAsync(outputPath);
    console.log(`图片保存成功: ${outputPath}`);
    
    // 手动释放内存
    image = null;
    if (global.gc) {
      global.gc();
    }
    
    return outputPath;
  } catch (error) {
    console.error('增强文档图像失败:', error);
    throw new Error(`增强文档图像失败: ${error.message}`);
  }
};

/**
 * 合并多张图片为长图
 * @param {string[]} imagePaths - 图片路径数组
 * @returns {Promise<string>} - 合并后的图片路径
 */
exports.mergeImages = async (imagePaths) => {
  try {
    console.log(`开始合并图片，共${imagePaths.length}张`);
    
    // 限制处理的图片数量
    const MAX_IMAGES = 10;
    if (imagePaths.length > MAX_IMAGES) {
      console.warn(`图片数量(${imagePaths.length})超过限制(${MAX_IMAGES})，将只处理前${MAX_IMAGES}张`);
      imagePaths = imagePaths.slice(0, MAX_IMAGES);
    }
    
    // 读取所有图片并调整大小
    const images = [];
    const MAX_DIMENSION = 1200; // 限制最大尺寸
    
    for (const imgPath of imagePaths) {
      console.log(`加载图片: ${imgPath}`);
      const img = await Jimp.read(imgPath);
      const resizedImg = resizeImageIfNeeded(img, MAX_DIMENSION);
      images.push(resizedImg);
      console.log(`图片加载完成: ${imgPath}, 尺寸: ${resizedImg.getWidth()}x${resizedImg.getHeight()}`);
    }
    
    // 计算合并后图片的尺寸
    const maxWidth = Math.min(MAX_DIMENSION, Math.max(...images.map(img => img.getWidth())));
    let totalHeight = 0;
    
    // 计算总高度并调整每张图片的宽度
    for (let i = 0; i < images.length; i++) {
      if (images[i].getWidth() !== maxWidth) {
        images[i].resize(maxWidth, Jimp.AUTO);
      }
      totalHeight += images[i].getHeight();
    }
    
    console.log(`合并后的图片尺寸: ${maxWidth}x${totalHeight}`);
    
    // 如果总高度过大，按比例缩小所有图片
    const MAX_HEIGHT = 5000;
    let scale = 1;
    if (totalHeight > MAX_HEIGHT) {
      scale = MAX_HEIGHT / totalHeight;
      console.log(`总高度(${totalHeight})超过限制(${MAX_HEIGHT})，将按比例缩小: ${scale}`);
      
      // 重新调整所有图片
      for (let i = 0; i < images.length; i++) {
        images[i].resize(Math.floor(images[i].getWidth() * scale), Math.floor(images[i].getHeight() * scale));
      }
      
      // 重新计算尺寸
      totalHeight = Math.floor(totalHeight * scale);
      maxWidth = Math.floor(maxWidth * scale);
      console.log(`缩小后的图片尺寸: ${maxWidth}x${totalHeight}`);
    }
    
    // 创建一个新的图像
    console.log(`创建合并图像: ${maxWidth}x${totalHeight}`);
    const mergedImage = new Jimp(maxWidth, totalHeight, 0xFFFFFFFF);
    
    // 逐个添加图片
    let currentHeight = 0;
    for (let i = 0; i < images.length; i++) {
      const img = images[i];
      console.log(`合并第${i+1}张图片，位置: (0, ${currentHeight})`);
      
      // 将图片合并到新图像中
      mergedImage.composite(img, 0, currentHeight);
      
      // 更新当前高度
      currentHeight += img.getHeight();
      
      // 释放单张图片的内存
      images[i] = null;
    }
    
    // 创建输出路径
    const outputPath = path.join(
      path.dirname(imagePaths[0]),
      `merged-${Date.now()}-${uuidv4().substring(0, 8)}.jpg`
    );
    
    console.log(`保存合并后的图片: ${outputPath}`);
    
    // 保存合并后的图像，降低质量以减少文件大小
    await mergedImage.quality(80).writeAsync(outputPath);
    console.log(`合并图片保存成功: ${outputPath}`);
    
    // 手动释放内存
    if (global.gc) {
      global.gc();
    }
    
    return outputPath;
  } catch (error) {
    console.error('合并图片失败:', error);
    throw new Error(`合并图片失败: ${error.message}`);
  }
};

/**
 * 生成PDF文档
 * @param {string[]} imagePaths - 图片路径数组
 * @param {string} title - PDF标题
 * @returns {Promise<string>} - 生成的PDF路径
 */
exports.generatePDF = async (imagePaths, title) => {
  try {
    console.log(`开始生成PDF，图片数量: ${imagePaths.length}`);
    
    // 限制处理的图片数量
    const MAX_IMAGES = 20;
    if (imagePaths.length > MAX_IMAGES) {
      console.warn(`图片数量(${imagePaths.length})超过限制(${MAX_IMAGES})，将只处理前${MAX_IMAGES}张`);
      imagePaths = imagePaths.slice(0, MAX_IMAGES);
    }
    
    // 创建PDF文件路径
    const outputPath = path.join(
      path.dirname(imagePaths[0]),
      `${title.replace(/[^a-zA-Z0-9]/g, '-')}-${Date.now()}.pdf`
    );
    
    // 创建一个PDF文档
    const doc = new PDFDocument({
      autoFirstPage: false,
      margin: 0,
      compress: true // 启用压缩
    });
    
    // 创建写入流
    const writeStream = fs.createWriteStream(outputPath);
    doc.pipe(writeStream);
    
    // 获取所有图片的尺寸，并限制大小
    const MAX_DIMENSION = 1500;
    const imagesInfo = [];
    
    for (const imgPath of imagePaths) {
      console.log(`处理PDF图片: ${imgPath}`);
      try {
        const img = await Jimp.read(imgPath);
        let width = img.getWidth();
        let height = img.getHeight();
        
        // 如果图片尺寸过大，进行缩放
        if (width > MAX_DIMENSION || height > MAX_DIMENSION) {
          if (width > height) {
            const scale = MAX_DIMENSION / width;
            width = MAX_DIMENSION;
            height = Math.floor(height * scale);
          } else {
            const scale = MAX_DIMENSION / height;
            height = MAX_DIMENSION;
            width = Math.floor(width * scale);
          }
          console.log(`图片尺寸调整为: ${width}x${height}`);
        }
        
        imagesInfo.push({
          path: imgPath,
          width,
          height
        });
        
        // 释放内存
        img = null;
      } catch (err) {
        console.error(`处理图片失败: ${imgPath}`, err);
        // 跳过处理失败的图片
      }
    }
    
    // 添加每张图片到PDF
    for (let i = 0; i < imagesInfo.length; i++) {
      const info = imagesInfo[i];
      console.log(`添加第${i+1}张图片到PDF: ${info.path}`);
      
      // 添加新页面，尺寸与图片匹配
      doc.addPage({
        size: [info.width, info.height],
        margin: 0
      });
      
      // 添加图片
      doc.image(info.path, 0, 0, {
        width: info.width,
        height: info.height
      });
    }
    
    console.log(`完成PDF生成，准备保存: ${outputPath}`);
    
    // 完成PDF
    doc.end();
    
    // 返回Promise，等待PDF写入完成
    return new Promise((resolve, reject) => {
      writeStream.on('finish', () => {
        console.log(`PDF保存成功: ${outputPath}`);
        resolve(outputPath);
      });
      writeStream.on('error', (err) => {
        console.error(`PDF保存失败: ${err.message}`);
        reject(err);
      });
    });
  } catch (error) {
    console.error('生成PDF失败:', error);
    throw new Error(`生成PDF失败: ${error.message}`);
  }
};